Skip to content

explorer: bounded disableDepthTestDistance to make dots visible over terrain (closes #185)#198

Merged
rdhyee merged 1 commit intoisamplesorg:mainfrom
rdhyee:fix/185-bounded-depth-test-bypass
May 10, 2026
Merged

explorer: bounded disableDepthTestDistance to make dots visible over terrain (closes #185)#198
rdhyee merged 1 commit intoisamplesorg:mainfrom
rdhyee:fix/185-bounded-depth-test-bypass

Conversation

@rdhyee
Copy link
Copy Markdown
Contributor

@rdhyee rdhyee commented May 10, 2026

Summary

Closes #185. Three-line change at the three viewer.h3Points.add() / viewer.samplePoints.add() sites, plus one new top-level constant.

Root cause

Cluster and sample point primitives are placed at altitude=0 (the WGS84 ellipsoid surface). Cesium world terrain is enabled by default, so terrain mesh in hilly regions rises hundreds to thousands of meters above ellipsoid — sea-level primitives are physically underground there and get depth-culled by Cesium's standard per-pixel depth test.

This is why the issue manifests over the Troodos range (Cyprus) and the hill country around Birmingham, AL but not over coastal/flat regions.

Diff

// New constant alongside SOURCE_VALUES / DEFAULT_POINT_BUDGET:
POINT_DEPTH_TEST_DISTANCE = 2.0e6  // meters; see doc comment for rationale

// Three .add() sites each gain one property:
viewer.h3Points.add({
    ...,
    scaleByDistance: scalar,
    disableDepthTestDistance: POINT_DEPTH_TEST_DISTANCE,  // issue #185
});

Why bounded (2.0e6), not POSITIVE_INFINITY

PR #181 tried disableDepthTestDistance: POSITIVE_INFINITY and was reverted via #183 because it caused:

  • Back-side-of-globe primitive bleed-through (points on the FAR hemisphere rendered through the Earth)
  • Broken hover/click pickability

A bounded 2,000 km distance preserves globe-ellipsoid occlusion at long range (no back-side bleed) while bypassing terrain occlusion at every interactive zoom altitude (point mode <120 km, res8 ≤300 km, res6 ≤3,000 km).

Experimental verification

Runtime-patched the live deploy at https://isamples.org/explorer.html with the user's western Cyprus / point altitude URL. Compared four toggles:

Toggle Cyprus visibility
T0 baseline (no fix, prod) ~0 dots visible over Troodos
T1 swap terrain → EllipsoidTerrainProvider minor improvement
T2 raise all primitives to height: 5000m significant — dots reappear
T3 disableDepthTestDistance: 2.0e6 (this PR) significant, equivalent to T2; no back-side bleed-through

The dots that appear under T2/T3 are not new data — they were always loaded, just depth-culled in T0.

Local preview run of quarto preview explorer.qmd against the same URL with this PR applied shows the same restored visibility.

What was ruled out

The hypotheses listed in #185's body:

  • Alpha-fill blending into bright satellite imagery — would not explain point-mode dots (pixelSize: 6, scaled to ~18-48 px) disappearing entirely.
  • Cesium PointPrimitive shader artifact at certain pixelSize/outlineWidth ratios — T5 force-bigger-pixelSize alone didn't restore visibility on hilly terrain; T3 did.
  • Atmosphere/translucent ocean layer — PR explorer: fix halo terrain occlusion via scene.globe.depthTestAgainstTerrain (v2) #184 already ruled out global scene settings as the cause.
  • GPU/DPR-specific — the bug reproduces in headless chromium at default viewport, so not high-DPR-specific.
  • heightReferenceCesium.PointPrimitive does not support heightReference (only PointGraphics / Entity API does). Switching the explorer to entities would be a much bigger lift than this PR.

Test plan

Refs

🤖 Generated with Claude Code

…terrain (closes isamplesorg#185)

Cluster and sample point primitives are placed at altitude=0 (the WGS84
ellipsoid surface). With Cesium world terrain enabled, terrain mesh in
hilly regions (Troodos in Cyprus, hill country around Birmingham AL,
etc.) rises hundreds to thousands of meters above ellipsoid — so points
at altitude=0 are physically *underground* in those regions and get
depth-culled by Cesium's standard per-pixel depth test.

The fix is one new property at each of the three .add() call sites:

  disableDepthTestDistance: POINT_DEPTH_TEST_DISTANCE  // 2.0e6 = 2,000 km

Bypass scope: only when the camera is closer than 2,000 km, which covers
every realistic interactive altitude (point mode <120 km, res8 cluster
up to ~300 km, res6 up to ~3,000 km — the upper end is technically
outside the bypass but at that altitude dots are tiny anyway).

Why bounded (2.0e6) and not POSITIVE_INFINITY: PR isamplesorg#181 used Infinity and
caused back-side-of-globe primitive bleed-through plus broke pickability
(was reverted via isamplesorg#183). A 2,000 km bound preserves globe-ellipsoid
occlusion at long range while bypassing terrain occlusion at every
interactive zoom.

Hypothesis source: Codex review of isamplesorg#185 identified sea-level placement
as the most likely root cause. Confirmed experimentally by runtime-
patching the live deploy:

  T0 baseline (no fix)                          Cyprus interior: ~0 dots
  T1 swap to EllipsoidTerrainProvider           minor improvement
  T2 raise primitives to height=5000m           significant improvement
  T3 disableDepthTestDistance: 2.0e6 (this PR)  significant, equivalent
                                                to T2, no back-side bleed

Closes isamplesorg#185.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rdhyee
Copy link
Copy Markdown
Contributor Author

rdhyee commented May 10, 2026

Codex review round 1 — LGTM

Findings: No blocking issues. POINT_DEPTH_TEST_DISTANCE at L439 is applied consistently at the three point creation paths.

Answers:

  1. 2.0e6 is a defensible bound. It covers point mode and the res8 range, while keeping the bypass roughly near the visible-horizon scale around the res8/res6 transition. Raising it to 3.0e6 would cover all res6 center-view cases, but it also expands the set of beyond-limb / occluded primitives that can render and pick. So I'd keep 2.0e6. Caveat (non-blocking): res6 clusters at camera distances between 2-3M can still depth-test and may still disappear over terrain. Preserves old overview behavior and avoids reintroducing the PR explorer: fix halo cutoff over terrain (disableDepthTestDistance) #181 failure mode.
  2. disableDepthTestDistance likely affects pick rendering too, because Cesium picking is based on rendering pickable primitives into a pick pass. The difference from POSITIVE_INFINITY is scope: inside 2M, terrain-hidden points become visible/pickable (intended); outside 2M, normal depth behavior remains. Far-side globe primitives are far beyond 2M, so the Infinity-style back-side pick/render pollution should not recur.
  3. Correct: PointPrimitive does not expose heightReference in current Cesium docs. PointGraphics does. Switching the explorer to entities would be a much bigger lift and probably not cleaner given the performance-sensitive cluster counts.
  4. Top-level is fine, arguably better. phase1 also needs the value, so putting it only inside zoomWatcher would force duplication. Matches DEFAULT_POINT_BUDGET placement.
  5. Residual risks (non-blocking): slight pop at the 2M slant-distance threshold; depth bypass applies to all depth-writing geometry, not only terrain; oblique views use point-camera distance, not camera altitude.

Sources checked: Cesium PointPrimitive, Scene, and PointGraphics docs.

LGTM, ready to merge.

Merging.

@rdhyee rdhyee merged commit 01ff174 into isamplesorg:main May 10, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

explorer: halo crescents / disappearing dots over hilly terrain (root cause not yet identified)

1 participant